/*
 misc设备 共享一个主设备号10 
 */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/cdev.h>
#include <linux/fs.h>             /* file_operations */
#include <linux/miscdevice.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/kernel.h>         /* for ARRAY_SIZE() */
#include <mach/gpio.h>		     /* for S5PV210_GPJ2() */
#include <plat/gpio-cfg.h>	     /* for s3c_gpio_cfgpin  S3C_GPIO_OUTPUT */
#include <mach/regs-gpio.h>
#include <linux/slab.h>

#define LED_NUM	ARRAY_SIZE(led_gpios)
#define DEVICE_NAME "leds"

static int led_gpios[]=
{
    S5PV210_GPJ2(0),
	S5PV210_GPJ2(1),
	S5PV210_GPJ2(2),
	S5PV210_GPJ2(3),
};

char kbuf[4]={0};

ssize_t leds_write(struct file *f,const char __user *u,size_t s,loff_t *l)
{
	int led=4,i;
	
	printk(KERN_EMERG"leds_write\r\n");
	
	if(copy_from_user(kbuf,u,led) != 0)return -ENOMEM;
    
	for(i=0;i<LED_NUM;i++)
	{
	   gpio_set_value(led_gpios[i],kbuf[i]);	   
	}

	return led;
}


static struct file_operations leds_fops = {
	.owner 				= THIS_MODULE,
	.write              = leds_write,
};


static struct miscdevice leds_misc_dev = {
	.minor 				= MISC_DYNAMIC_MINOR,  //动态分配次设备号
	.name 				= DEVICE_NAME,
	.fops 				= &leds_fops,
};


int __init leds_init(void)
{
    int i, ret;
	
	for(i =0 ;i<LED_NUM ;i++)
	{
		ret = gpio_request(led_gpios[i], "leds");//申请GPIO资源 如有被暂用则申请失败
		
		if(ret)
        {
			printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME, led_gpios[i], ret);
                    
			return ret;
		}
		
		gpio_direction_output(led_gpios[i],1);
		
		/*等价于这两行
		  s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT);
		  gpio_set_value(led_gpios[i],1);
		 */
	}
    
	ret = misc_register(&leds_misc_dev);
	
	printk(DEVICE_NAME"\tinitialized\n");
	
	return 0;
}

void __exit leds_exit(void)
{
	int i;
    
	for (i = 0; i < LED_NUM; i++)
		gpio_free(led_gpios[i]);

	misc_deregister(&leds_misc_dev);
    
	return;
}

module_init(leds_init);//insmod ***.ko
module_exit(leds_exit);//rmmod ***.ko
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yang Zhengyou");